/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.applicatioN.controllers;

import com.applicatioN.controllers.exceptions.IllegalOrphanException;
import com.applicatioN.controllers.exceptions.NonexistentEntityException;
import com.applicatioN.controllers.exceptions.PreexistingEntityException;
import com.applicatioN.entities.Ecole;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import com.applicatioN.entities.Etudier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author Asus_k53s
 */
public class EcoleJpaController implements Serializable {

    public EcoleJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Ecole ecole) throws PreexistingEntityException, Exception {
        if (ecole.getEtudierCollection() == null) {
            ecole.setEtudierCollection(new ArrayList<Etudier>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<Etudier> attachedEtudierCollection = new ArrayList<Etudier>();
            for (Etudier etudierCollectionEtudierToAttach : ecole.getEtudierCollection()) {
                etudierCollectionEtudierToAttach = em.getReference(etudierCollectionEtudierToAttach.getClass(), etudierCollectionEtudierToAttach.getEtudierPK());
                attachedEtudierCollection.add(etudierCollectionEtudierToAttach);
            }
            ecole.setEtudierCollection(attachedEtudierCollection);
            em.persist(ecole);
            for (Etudier etudierCollectionEtudier : ecole.getEtudierCollection()) {
                Ecole oldEcoleOfEtudierCollectionEtudier = etudierCollectionEtudier.getEcole();
                etudierCollectionEtudier.setEcole(ecole);
                etudierCollectionEtudier = em.merge(etudierCollectionEtudier);
                if (oldEcoleOfEtudierCollectionEtudier != null) {
                    oldEcoleOfEtudierCollectionEtudier.getEtudierCollection().remove(etudierCollectionEtudier);
                    oldEcoleOfEtudierCollectionEtudier = em.merge(oldEcoleOfEtudierCollectionEtudier);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findEcole(ecole.getNom()) != null) {
                throw new PreexistingEntityException("Ecole " + ecole + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Ecole ecole) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Ecole persistentEcole = em.find(Ecole.class, ecole.getNom());
            Collection<Etudier> etudierCollectionOld = persistentEcole.getEtudierCollection();
            Collection<Etudier> etudierCollectionNew = ecole.getEtudierCollection();
            List<String> illegalOrphanMessages = null;
            for (Etudier etudierCollectionOldEtudier : etudierCollectionOld) {
                if (!etudierCollectionNew.contains(etudierCollectionOldEtudier)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Etudier " + etudierCollectionOldEtudier + " since its ecole field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Etudier> attachedEtudierCollectionNew = new ArrayList<Etudier>();
            for (Etudier etudierCollectionNewEtudierToAttach : etudierCollectionNew) {
                etudierCollectionNewEtudierToAttach = em.getReference(etudierCollectionNewEtudierToAttach.getClass(), etudierCollectionNewEtudierToAttach.getEtudierPK());
                attachedEtudierCollectionNew.add(etudierCollectionNewEtudierToAttach);
            }
            etudierCollectionNew = attachedEtudierCollectionNew;
            ecole.setEtudierCollection(etudierCollectionNew);
            ecole = em.merge(ecole);
            for (Etudier etudierCollectionNewEtudier : etudierCollectionNew) {
                if (!etudierCollectionOld.contains(etudierCollectionNewEtudier)) {
                    Ecole oldEcoleOfEtudierCollectionNewEtudier = etudierCollectionNewEtudier.getEcole();
                    etudierCollectionNewEtudier.setEcole(ecole);
                    etudierCollectionNewEtudier = em.merge(etudierCollectionNewEtudier);
                    if (oldEcoleOfEtudierCollectionNewEtudier != null && !oldEcoleOfEtudierCollectionNewEtudier.equals(ecole)) {
                        oldEcoleOfEtudierCollectionNewEtudier.getEtudierCollection().remove(etudierCollectionNewEtudier);
                        oldEcoleOfEtudierCollectionNewEtudier = em.merge(oldEcoleOfEtudierCollectionNewEtudier);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = ecole.getNom();
                if (findEcole(id) == null) {
                    throw new NonexistentEntityException("The ecole with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Ecole ecole;
            try {
                ecole = em.getReference(Ecole.class, id);
                ecole.getNom();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The ecole with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Etudier> etudierCollectionOrphanCheck = ecole.getEtudierCollection();
            for (Etudier etudierCollectionOrphanCheckEtudier : etudierCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Ecole (" + ecole + ") cannot be destroyed since the Etudier " + etudierCollectionOrphanCheckEtudier + " in its etudierCollection field has a non-nullable ecole field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(ecole);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Ecole> findEcoleEntities() {
        return findEcoleEntities(true, -1, -1);
    }

    public List<Ecole> findEcoleEntities(int maxResults, int firstResult) {
        return findEcoleEntities(false, maxResults, firstResult);
    }

    private List<Ecole> findEcoleEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Ecole.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Ecole findEcole(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Ecole.class, id);
        } finally {
            em.close();
        }
    }

    public int getEcoleCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Ecole> rt = cq.from(Ecole.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
